package gameObject.resources3D
{
	import away3d.animators.SkeletonAnimator;
	import away3d.containers.ObjectContainer3D;
	
	import com.riaidea.utils.zip.ZipArchive;
	import com.riaidea.utils.zip.ZipEvent;
	import com.riaidea.utils.zip.ZipFile;
	
	import flash.events.Event;
	import flash.geom.Matrix3D;
	import flash.geom.Vector3D;
	
	
	/**
	 * 通过加载一个包含所有机甲模型文件的zip文件取出机甲模型资源
	 */
	public class RobotResource extends ResourceBase
	{
		private var _legType:String;
		private var _bodyType:String;
		
		private var loader:ZipArchive;
		
		private var _robURL:String;
		private var _legMeshURL:String;
		private var _legSkeURL:String;
		private var _bodyMeshURL:String;
		private var _bodySkeURL:String;
		////////////////////////////////////////////
		private var conBone:String;
		private var _connector:ObjectContainer3D;
		private var conPar:ObjectContainer3D;
		
		private var wp1:Vector.<WeaponConnector> = new Vector.<WeaponConnector>;
		private var wp2:Vector.<WeaponConnector> = new Vector.<WeaponConnector>;
		
		private var loadedObj:uint=0;
		private var baseIndex:uint;
		////////////////////////////////////////////
		private var _legMesh:GameMesh;
		private var _bodyMesh:GameMesh;
		
		private var _legAnimator:SkeletonAnimator;
		private var _bodyAnimator:SkeletonAnimator;
		
		////////////////////////////////////////////
		
		public function get connector():ObjectContainer3D
		{
			return _connector;
		}
		
		/**
		 * 武器接口点
		 * @param type 1:主武器接口   2：副武器接口
		 */
		public function getWeaponConnector(type:uint,id:uint):WeaponConnector
		{
			switch(type)
			{
				case 1:
					return wp1[id];
					break;
				case 2:
					return wp2[id];
					break;
				
				default:
					return null;
					break;
			}
		}
		
		public function get bodyMesh():GameMesh
		{
			return _bodyMesh;
		}
		
		public function get legMesh():GameMesh
		{
			return _legMesh;
		}
		
		public function get center():Number
		{
			if(_legMesh && _bodyMesh)
			{
				return conPar.y;
			}else return 0;
		}
		
		public function RobotResource(id:int,LOD:String)
		{
			super();
			
			_id = id;
			_LOD = LOD;
		}
		////////////////////////////////
		override public function load():void
		{
			if(_id>=0 && !_legMesh && !_bodyMesh)
			{
				_robURL = Global.assetPath+"models/robots/rob"+String(_id)+"_"+_LOD+".zip";
				
				loader = new ZipArchive;
				loader.addEventListener(ZipEvent.ERROR,onError);
				loader.addEventListener(ZipEvent.INIT,zipFileLoaded);
				loader.load(_robURL);
			}
		}
		
		private function onError(e:ZipEvent):void
		{
			var errorInfo:String ="ZIP资源异常："+ _robURL;
			throw new Error(errorInfo);
		}
		
		override public function dispose():void
		{
			super.dispose();
			loader.removeEventListener(ZipEvent.ERROR,onError);
			loader.removeEventListener(ZipEvent.INIT,zipFileLoaded);
			
			if(_legAnimator)_legAnimator.stop();
			if(_bodyAnimator)_bodyAnimator.stop();
			Global.stage.removeEventListener(Event.ENTER_FRAME,fitTransform);
		}
		
		private function zipFileLoaded(e:ZipEvent):void
		{
			var xmlName:String = "rob"+String(_id)+"_"+_LOD+"_ini.xml";
			var xmlFile:ZipFile = loader.getFileByName(xmlName);
			var xml:XML = new XML(xmlFile.data);
			
			_bodyType = xml.@body;
			_legType = xml.@leg;
			
			conBone = String(xml.@conBone);
			
			_connector = new ObjectContainer3D;
			_connector.x = Number(xml.@conX);
			_connector.y = Number(xml.@conY);
			_connector.z = Number(xml.@conZ);
			
			for each(var pt:XML in xml.wp1.pt)
			{
				var v:Vector3D = new Vector3D;
				v.x = Number(pt.@x);
				v.y = Number(pt.@y);
				v.z = Number(pt.@z);
				
				var connector:WeaponConnector = new WeaponConnector(1,_LOD);
				connector.x = v.x;
				connector.y = v.y;
				connector.z = v.z;
				
				wp1.push(connector);
				_connector.addChild(connector);
			}
			
			for each(pt in xml.wp2.pt)
			{
				v = new Vector3D;
				v.x = Number(pt.@x);
				v.y = Number(pt.@y);
				v.z = Number(pt.@z);
				
				connector = new WeaponConnector(2,_LOD);
				connector.x = v.x;
				connector.y = v.y;
				connector.z = v.z;
				
				wp2.push(connector);
				_connector.addChild(connector);
			}
			///////////////////
			_legMeshURL =  Global.assetPath+"models/robots/"+xml.@leg;
			
			var legFile:ZipFile = loader.getFileByName(xml.@leg);
			var legMeshData:XML = new XML(legFile.data);
			
			var skeFileName:String = legMeshData.@skeleton;
			var strAry:Array = skeFileName.split("models/robots/");
			skeFileName = strAry[1];
			
			var legSkeFile:ZipFile =  loader.getFileByName(skeFileName);
			var legSkeData:XML =  new XML(legSkeFile.data);
			
			_legMesh = new GameMesh(_legMeshURL,legMeshData,legSkeData);
			
			//----------------------------------
			_bodyMeshURL =  Global.assetPath+"models/robots/"+xml.@body;
			
			var bodyFile:ZipFile = loader.getFileByName(xml.@body);
			var bodyMeshData:XML = new XML(bodyFile.data);
			
			var bodySkeData:XML = null;
			skeFileName = bodyMeshData.@skeleton;
			if(skeFileName!="")
			{
				strAry = skeFileName.split("models/robots/");
				skeFileName = strAry[1];
				
				var bodySkeFile:ZipFile =  loader.getFileByName(skeFileName);
				bodySkeData =  new XML(legSkeFile.data);
			}
			
			_bodyMesh = new GameMesh(_bodyMeshURL,bodyMeshData,bodySkeData);
			
			//----------------------------------
			_legMesh.addEventListener(Event.COMPLETE,legLoaded);
			_bodyMesh.addEventListener(Event.COMPLETE,bodyLoaded);
			
			loadedObj=0;
			
			_legMesh.load();
			_bodyMesh.load();
		}
		
		private function legLoaded(e:Event):void
		{
			_legMesh.removeEventListener(Event.COMPLETE,legLoaded);
			
			loadedObj++;
			_legAnimator = _legMesh.animator as SkeletonAnimator;
			if(loadedObj==2)setup();
		}
		
		private function bodyLoaded(e:Event):void
		{
			_bodyMesh.removeEventListener(Event.COMPLETE,bodyLoaded);
			
			loadedObj++;
			if(loadedObj==2)setup();
		}
		
		private function setup():void
		{
			baseIndex = _legAnimator.skeleton.jointIndexFromName(conBone); 
			
			conPar = new ObjectContainer3D;
			addChild(conPar);
			
			var trans:Matrix3D = new Matrix3D;
			trans.copyRawDataFrom(_legAnimator.skeleton.joints[baseIndex].inverseBindPose);
			trans.invert();
			
			conPar.transform = trans;
			_connector.rotationX = -90;
			_connector.rotationZ = 90;
			
			addChild(_legMesh);
			conPar.addChild(_connector);
			_connector.addChild(_bodyMesh);
			
			dispatchEvent(new Event(Event.COMPLETE));
			Global.stage.addEventListener(Event.ENTER_FRAME,fitTransform);
		}
		
		private function fitTransform(e:Event):void
		{
			if(_legAnimator.globalPose.jointPoses.length>0)
				conPar.transform = _legAnimator.globalPose.jointPoses[baseIndex].toMatrix3D();
		}
	}
}